package cn.geekyspace.scanhive.infrastructure.ui;

import cn.geekyspace.scanhive.domain.service.OperatorUserHistoryService;
import jakarta.annotation.PreDestroy;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.LinkedHashSet;
import java.util.List;

@Data
@Slf4j
@Component
@RequiredArgsConstructor
public class UIExtendField {

    private TextField operatorUser;

    private final UILogger uiLogger;
    private final OperatorUserHistoryService historyService;


    // 本地缓存历史记录
    private final LinkedHashSet<String> history = new LinkedHashSet<>();
    // 用于保存新增或操作过的记录
    private final LinkedHashSet<String> dirtyHistory = new LinkedHashSet<>();

    // 候选项游标（用于上下键选择）
    private int historyIndex = -1;

    public void setOperatorUser(TextField operatorUser) {
        this.operatorUser = operatorUser;

        // 初始化历史数据
        historyService.getRecentHistory(50)
                .forEach(h -> history.add(h.getUsername()));

        // 设置默认值：取最新一条历史记录
        if (!history.isEmpty()) {
            operatorUser.setText(history.iterator().next());
        }

        // 候选菜单（用于模糊提示）
        ContextMenu suggestionsMenu = new ContextMenu();

        // -----------------------------
        // 键盘事件：上下键选择候选，回车确认
        // -----------------------------
        operatorUser.setOnKeyPressed(event -> {
            // 如果提示菜单正在显示
            if (suggestionsMenu.isShowing()) {
                int size = suggestionsMenu.getItems().size();
                if (size == 0) return;

                // 按下 ↓ 键
                if (event.getCode() == KeyCode.DOWN) {
                    historyIndex = (historyIndex + 1) % size;
                    highlightMenuItem(suggestionsMenu, historyIndex);
                    event.consume();
                }
                // 按下 ↑ 键
                else if (event.getCode() == KeyCode.UP) {
                    historyIndex = (historyIndex - 1 + size) % size;
                    highlightMenuItem(suggestionsMenu, historyIndex);
                    event.consume();
                }
            } else if (event.getCode() == KeyCode.ENTER) {
                // 没有候选框时，直接保存输入
                String current = operatorUser.getText().trim();
                if (!current.isEmpty()) {
                    history.add(current);
                    dirtyHistory.add(current);  // 标记新增或操作过
                    uiLogger.success("确认操作员为 "+ current);
                }
                historyIndex = -1;
                suggestionsMenu.hide();
            }
        });


        // -----------------------------
        // 文本变化监听，模糊匹配提示
        // -----------------------------
        operatorUser.textProperty().addListener((obs, oldText, newText) -> {
            if (newText.isEmpty()) {
                suggestionsMenu.hide();
            } else {
                List<String> filtered = history.stream()
                        .filter(item -> item.toLowerCase().contains(newText.toLowerCase()))
                        .toList();

                if (!filtered.isEmpty()) {
                    suggestionsMenu.getItems().clear();
                    for (String item : filtered) {
                        MenuItem menuItem = new MenuItem(item);
                        menuItem.setOnAction(e -> {
                            operatorUser.setText(item);
                            operatorUser.positionCaret(item.length());
                            suggestionsMenu.hide();
                            history.add(item);
                            dirtyHistory.add(item); // 标记为操作过
                        });
                        suggestionsMenu.getItems().add(menuItem);
                    }
                    historyIndex = -1; // 重置游标
                    suggestionsMenu.show(operatorUser,
                            operatorUser.localToScreen(0, operatorUser.getHeight()).getX(),
                            operatorUser.localToScreen(0, operatorUser.getHeight()).getY()
                    );
                } else {
                    suggestionsMenu.hide();
                }
            }
        });
    }

    /**
     * 高亮 ContextMenu 中的某个 MenuItem
     */
    private void highlightMenuItem(ContextMenu menu, int index) {
        for (int i = 0; i < menu.getItems().size(); i++) {
            MenuItem item = menu.getItems().get(i);
            item.setStyle(i == index
                    ? "-fx-background-color: #3399ff; -fx-text-fill: white;"
                    : "");
        }
    }

    /**
     * 程序关闭或窗口关闭时调用，将本地缓存写入数据库
     */
    @PreDestroy
    public void saveHistoryToDatabase() {
        if (!dirtyHistory.isEmpty()) {
            historyService.saveOrUpdateHistoryBatch(dirtyHistory.stream().toList());
            log.info("新增/操作过的历史已保存到数据库，共 {} 条", dirtyHistory.size());
            dirtyHistory.clear();
        }
    }
}
